-- Scroll
-- create by chendh
-- 滚动容器相关工具函数

-------------------------------------------------------------------------------
-- 初始化滚动容器内的单元格（仅针对横向滚动容器）
-- @param windowNode    界面节点
-- @param scrollNode    容器节点
-- @param itemNode      单元格的节点
-- @param totalNum      单元格总数
-- @param maxRowNum     最大行数
-- @param pageColNum    单页可以显示下的列数
-- @param wGap          单元格间距(横向) 这里作为最小值使用
-- @param hGap          单元格间距(纵向)
-- @param iconWidth     单元格宽度
-- @param iconHeight    单元格高度
-- @param topHGap       上方留白
-- @param leftWGap      左右留白  这里作为最小值使用
-- @param touchEvent    点击事件注册函数
function initScrollGridsHorizontal(windowNode, scrollNode, itemNode, totalNum, maxRowNum, pageColNum, wGap, hGap, iconWidth, iconHeight, topHGap, leftWGap, touchEvent)
    local w = DESIGN_WIDTH;
    local h = DESIGN_HEIGHT;

    -- 计算单元格分布情况
    local gridList = sortGrids(totalNum, maxRowNum, pageColNum);

    -- 行数
    local rowNum = #gridList;

    -- 列数
    local maxColNum = 0;

    -- 取所有行的列数的最大值作为最大列数
    for _, rowList in ipairs(gridList) do
        if type(rowList) == "table" then
            maxColNum = math.max(maxColNum, #rowList);
        end
    end

    -- 先计算总高度
    local totalHeight = rowNum * (iconHeight + hGap) - hGap + topHGap;
    local totalWidth  = maxColNum * (iconWidth + wGap) - wGap + (leftWGap * 2);

    -- 先获取下显示区域的宽度和高度
    local areaWidth = scrollNode:getInnerContainerSize().width;
    local areaHeight = scrollNode:getInnerContainerSize().height;

    scrollNode:setInnerContainerSize(cc.size(totalWidth, scrollNode:getInnerContainerSize().height));
    local widget = replaceNodeWithWidget(itemNode);

    for i = 1, rowNum do
        for j = 1, #gridList[i] do
            local child = widget:clone();
            child:setName("item" .. gridList[i][j]);
            child.index = gridList[i][j];

            -- 计算单元格坐标
            -- 这个坐标将是单元格的描点所在
            local x = (j - 1) * (iconWidth + wGap) + iconWidth / 2 + leftWGap;
            local y = (maxRowNum - i) * (iconHeight + hGap) - hGap + topHGap + iconHeight / 2 + scrollNode:getInnerContainerSize().height - scrollNode:getInnerContainerSize().height;

            if touchEvent then
                touchEvent(windowNode, child);
            end

            child:setPositionX(x);
            child:setPositionY(y);

            scrollNode:addChild(child)
            table.insert(scrollNode.rows, child)
        end
    end
end

----------------------------------------------
-- 单元格排序
-- @param totalNum      单元格总数
-- @param maxRowNum     最大行数
-- @param pageColNum    单页可以显示下的列数
function sortGrids(totalNum, maxRowNum, pageColNum)
    local ret = {};
    local maxColNum = math.ceil(totalNum / maxRowNum);

    if totalNum >= maxRowNum * pageColNum then
        -- 如果数据数量足够绘满一页，那么就竖向排列
        -- 1， 3， 5， 7， 9
        -- 2， 4， 6， 8， 10
        for i = 1, maxRowNum do
            for j = 1, maxColNum do
                local num = (j - 1) * maxRowNum + i;

                if num <= totalNum then
                    if not ret[i] then
                        ret[i] = {}
                    end

                    table.insert(ret[i], num);
                end
            end
        end
    else
        -- 不足一页的情况下，那么就横向排序排序
        -- 1， 2， 3， 4， 5
        -- 6， 7， 8，
        for i = 1, maxRowNum do
            for j = 1, pageColNum do
                local num = (i - 1) * pageColNum + j;
                if num <= totalNum then
                    if not ret[i] then
                        ret[i] = {}
                    end
                    table.insert(ret[i], num);
                end
            end
        end
    end

    return ret;
end

-------------------------------------------------------------------------------
-- 初始化滚动容器内的单元格（仅针对竖向滚动容器）
-- @param windowNode    界面节点
-- @param scrollNode    容器节点
-- @param itemNode      单元格的节点
-- @param totalNum      单元格总数
-- @param pageRowNum    单页可以显示下的行数
-- @param maxColNum     最大列数
-- @param wGap          单元格间距(横向) 这里作为最小值使用
-- @param hGap          单元格间距(纵向)
-- @param iconWidth     单元格宽度
-- @param iconHeight    单元格高度
-- @param topHGap       上方留白
-- @param bottomHGap    下方留白
-- @param leftWGap      左右留白  这里作为最小值使用
-- @param touchEvent    点击事件注册函数
function initScrollGridsVertical(windowNode, scrollNode, itemNode, totalNum, pageRowNum, maxColNum, wGap, hGap, iconWidth, iconHeight, topHGap, bottomHGap, leftWGap, touchEvent)
    local w = DESIGN_WIDTH;
    local h = DESIGN_HEIGHT;

    -- 计算单元格分布情况
    local gridList = sortGridsEx(totalNum, pageRowNum, maxColNum);

    -- 行数
    local rowNum = #gridList;
    local colNum = 0;

    -- 取所有行的列数的最大值作为最大列数
    for _, rowList in ipairs(gridList) do
        if type(rowList) == "table" then
            colNum = math.max(colNum, #rowList);
        end
    end

    -- 先计算总高度
    local totalHeight = rowNum * (iconHeight + hGap) - hGap + topHGap + bottomHGap;
    local totalWidth  = colNum * (iconWidth + wGap) - wGap + (leftWGap * 2);

    -- 先获取下显示区域的宽度和高度
    local areaWidth = scrollNode:getInnerContainerSize().width;
    local areaHeight = scrollNode:getInnerContainerSize().height;

    wGap = (areaWidth - maxColNum * iconWidth) / (maxColNum + 1);
    leftWGap = wGap;

    scrollNode:setInnerContainerSize(cc.size(scrollNode:getInnerContainerSize().width, totalHeight));
    local widget = replaceNodeWithWidget(itemNode);

    for i = 1, rowNum do
        for j = 1, #gridList[i] do
            local child = widget:clone();
            child:setName("item" .. gridList[i][j]);
            child.index = gridList[i][j];

            -- 计算单元格坐标
            -- 这个坐标将是单元格的描点所在
            local x = (j - 1) * (iconWidth + wGap) + iconWidth / 2 + leftWGap;
            local y = scrollNode:getInnerContainerSize().height - topHGap - (i - 1) * (iconHeight + hGap) - iconHeight / 2;

            if touchEvent then
                touchEvent(windowNode, child);
            end

            child:setPositionX(x);
            child:setPositionY(y);

            scrollNode:addChild(child)
            table.insert(scrollNode.rows, child)
        end
    end
end

----------------------------------------------
-- 单元格排序
-- @param totalNum      单元格总数
-- @param pageRowNum    单页可以显示下的行数
-- @param maxColNum     最大列数
function sortGridsEx(totalNum, pageRowNum, maxColNum)
    local ret = {};
    local maxRowNum = math.ceil(totalNum / maxColNum);

    -- 横向排序排序
    -- 1， 2， 3，
    -- 4,  5,  6，
    -- 7， 8，
    for i = 1, maxRowNum do
        for j = 1, maxColNum do
            local num = (i - 1) * maxColNum + j;
            if num <= totalNum then
                if not ret[i] then
                    ret[i] = {}
                end
                table.insert(ret[i], num);
            end
        end
    end

    return ret;
end

-------------------------------------------------------------------------------
-- 初始化滚动容器内的单元格（仅针对既可纵向滚动又可横向滚动的容器）
-- @param windowNode    界面节点
-- @param scrollNode    容器节点
-- @param itemNode      单元格的节点
-- @param totalNum      单元格总数
-- @param rowNum        行数
-- @param colNum        列数
-- @param wGap          单元格间距(横向)
-- @param hGap          单元格间距(纵向)
-- @param iconWidth     单元格宽度
-- @param iconHeight    单元格高度
-- @param topHGap       上方留白
-- @param bottomHGap    下方留白
-- @param leftWGap      左侧留白
-- @param rightWGap     右侧留白
-- @param touchEvent    点击事件注册函数
function initScrollGrids(windowNode, scrollNode, itemNode, totalNum, rowNum, colNum, wGap, hGap, iconWidth, iconHeight, topHGap, bottomHGap, leftWGap, rightWGap, touchEvent)
    local w = DESIGN_WIDTH;
    local h = DESIGN_HEIGHT;

    -- 计算单元格分布情况
    local gridList = sortGridsEx(totalNum, rowNum, colNum);

    -- 行数
    local rowNum = #gridList;
    local colNum = 0;

    -- 取所有行的列数的最大值作为最大列数
    for _, rowList in ipairs(gridList) do
        if type(rowList) == "table" then
            colNum = math.max(colNum, #rowList);
        end
    end

    -- 先计算总高度
    local totalHeight = rowNum * (iconHeight + hGap) - hGap + topHGap + bottomHGap;
    local totalWidth  = colNum * (iconWidth + wGap) - wGap + leftWGap + rightWGap;

    -- 设置滚动区域大小
    scrollNode:setInnerContainerSize(cc.size(totalWidth, totalHeight));

    local widget = replaceNodeWithWidget(itemNode);

    for i = 1, rowNum do
        for j = 1, #gridList[i] do
            local child = widget:clone();
            child:setName("item" .. gridList[i][j]);
            child.index = gridList[i][j];

            -- 计算单元格坐标
            -- 这个坐标将是单元格的描点所在
            local x = (j - 1) * (iconWidth + wGap) + iconWidth / 2 + leftWGap;
            local y = scrollNode:getInnerContainerSize().height - topHGap - (i - 1) * (iconHeight + hGap) - iconHeight / 2;

            if touchEvent then
                touchEvent(windowNode, child);
            end

            child:setPositionX(x);
            child:setPositionY(y);

            scrollNode:addChild(child)
            table.insert(scrollNode.rows, child)
        end
    end
end

----------------------------------------------
-- 滑动到最顶部
-- @param scrollview    滚动容器
function scrollToTop(scrollview)
    local viewHeight  = scrollview:getContentSize().height;
    local innerHeight = scrollview:getInnerContainerSize().height;
    scrollview:getInnerContainer():setPositionY(viewHeight - innerHeight);
end

----------------------------------------------
-- 滑动到最左侧
-- @param scrollview    滚动容器
function scrollToTopLeft(scrollview)
    scrollview:getInnerContainer():setPositionX(0);
end
